x86_emulate: Allow writeback-avoidance optimisation to be defeated by
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 21 Feb 2008 14:50:27 +0000 (14:50 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 21 Feb 2008 14:50:27 +0000 (14:50 +0000)
the caller. This is used in cases where the writeback may be to an
MMIO region with side effects (the APIC EOI register is the main
example of this).

Also fix up build of the x86_emulate user-space test harness.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
tools/tests/test_x86_emulator.c
xen/arch/x86/hvm/emulate.c
xen/arch/x86/mm.c
xen/arch/x86/mm/shadow/common.c
xen/arch/x86/x86_emulate.c
xen/include/asm-x86/x86_emulate.h

index f261e7f4daecd291ee696792b61565ece0a5ba50..fe48921b59e713c2d7a6fd4d75317dfe458cca60 100644 (file)
@@ -118,6 +118,7 @@ int main(int argc, char **argv)
 #endif
 
     ctxt.regs = &regs;
+    ctxt.force_writeback = 0;
     ctxt.addr_size = 32;
     ctxt.sp_size   = 32;
 
index 73649313acaf0f7df00f1cbcb4aa48de8aedba6d..2bbdb505e902cba6cf15007bf3f4d93ebeef470d 100644 (file)
@@ -722,6 +722,7 @@ void hvm_emulate_prepare(
     struct cpu_user_regs *regs)
 {
     hvmemul_ctxt->ctxt.regs = regs;
+    hvmemul_ctxt->ctxt.force_writeback = 1;
     hvmemul_ctxt->seg_reg_accessed = 0;
     hvmemul_ctxt->seg_reg_dirty = 0;
     hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt);
index 469842787e78d0b82180650e5fb67f4739b8b523..e84b185598eedeb26d35aa67a3821ea09a2f62c0 100644 (file)
@@ -3671,6 +3671,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr,
         goto bail;
 
     ptwr_ctxt.ctxt.regs = regs;
+    ptwr_ctxt.ctxt.force_writeback = 0;
     ptwr_ctxt.ctxt.addr_size = ptwr_ctxt.ctxt.sp_size =
         is_pv_32on64_domain(d) ? 32 : BITS_PER_LONG;
     ptwr_ctxt.cr2 = addr;
index d30e7e721a2ba46b311fb6c0acc87732957b244d..240d9100f0505c4fd639dc089d52c4e7823f396c 100644 (file)
@@ -385,6 +385,7 @@ struct x86_emulate_ops *shadow_init_emulation(
     unsigned long addr;
 
     sh_ctxt->ctxt.regs = regs;
+    sh_ctxt->ctxt.force_writeback = 0;
 
     if ( !is_hvm_vcpu(v) )
     {
index b240a0a48ec7f1bf90c3970746d1f36149c03b1a..fb3280d5056fe91d69375742e4c9f840e12ecb29 100644 (file)
@@ -24,6 +24,7 @@
 #ifndef __XEN__
 #include <stddef.h>
 #include <stdint.h>
+#include <string.h>
 #include <public/xen.h>
 #else
 #include <xen/config.h>
@@ -1983,7 +1984,8 @@ x86_emulate(
         }
         break;
     case OP_MEM:
-        if ( !(d & Mov) && (dst.orig_val == dst.val) )
+        if ( !(d & Mov) && (dst.orig_val == dst.val) &&
+             !ctxt->force_writeback )
             /* nothing to do */;
         else if ( lock_prefix )
             rc = ops->cmpxchg(
index 53d12f52be617520f53e310b430cc9806c8aca97..d92df355d3fd7773efdc4f2913f138c8990fa264 100644 (file)
@@ -56,17 +56,17 @@ enum x86_segment {
  * segment descriptor. It happens to match the format of an AMD SVM VMCB.
  */
 typedef union segment_attributes {
-    u16 bytes;
+    uint16_t bytes;
     struct
     {
-        u16 type:4;    /* 0;  Bit 40-43 */
-        u16 s:   1;    /* 4;  Bit 44 */
-        u16 dpl: 2;    /* 5;  Bit 45-46 */
-        u16 p:   1;    /* 7;  Bit 47 */
-        u16 avl: 1;    /* 8;  Bit 52 */
-        u16 l:   1;    /* 9;  Bit 53 */
-        u16 db:  1;    /* 10; Bit 54 */
-        u16 g:   1;    /* 11; Bit 55 */
+        uint16_t type:4;    /* 0;  Bit 40-43 */
+        uint16_t s:   1;    /* 4;  Bit 44 */
+        uint16_t dpl: 2;    /* 5;  Bit 45-46 */
+        uint16_t p:   1;    /* 7;  Bit 47 */
+        uint16_t avl: 1;    /* 8;  Bit 52 */
+        uint16_t l:   1;    /* 9;  Bit 53 */
+        uint16_t db:  1;    /* 10; Bit 54 */
+        uint16_t g:   1;    /* 11; Bit 55 */
     } fields;
 } __attribute__ ((packed)) segment_attributes_t;
 
@@ -75,10 +75,10 @@ typedef union segment_attributes {
  * Again, this happens to match the format of an AMD SVM VMCB.
  */
 struct segment_register {
-    u16        sel;
+    uint16_t   sel;
     segment_attributes_t attr;
-    u32        limit;
-    u64        base;
+    uint32_t   limit;
+    uint64_t   base;
 } __attribute__ ((packed));
 
 /*
@@ -368,6 +368,9 @@ struct x86_emulate_ctxt
 
     /* Stack pointer width in bits (16, 32 or 64). */
     unsigned int sp_size;
+
+    /* Set this if writes may have side effects. */
+    int force_writeback;
 };
 
 /*